package com.pv.bfc.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.pv.bfc.model.BriefcaseUser;
import com.pv.bfc.model.Document;
import com.pv.bfc.model.Folder;

@Transactional
@Repository
@RemoteProxy(name = "UserRepo")
public class FolderJpaRepository implements FolderRepository {

	private EntityManager entityManager;
	private SessionFactory sessionFactory;
	private DataFieldMaxValueIncrementer folderIdIncrementor;

	private static final Log logger = LogFactory
			.getLog(FolderJpaRepository.class);

	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	@Transactional
	public void deleteFolder(Folder folder) {
		if (logger.isInfoEnabled()) {
			logger.info("Deleting " + folder);
		}
		entityManager.remove(folder);

	}

	@Transactional
	public void persistFolder(Folder folder) {
		int i = getFolderIdIncrementor().nextIntValue();
		folder.setFolderid(i);
		if (logger.isInfoEnabled()) {
			logger.info("Adding " + folder);
		}
		entityManager.persist(folder);
	}

	@Transactional
	public void removeDocumentFromFolder(Integer id) {
		if (logger.isInfoEnabled()) {
			logger.info("Removing Document from Folder " + id);
		}
		Query q = entityManager.createNamedQuery("deleteDocument");
		q.setParameter(1, id);
		q.executeUpdate();

	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	@RemoteMethod
	public List<Folder> retrieveAllFolders() {
		Query q = entityManager.createNamedQuery("allFolders");
		return q.getResultList();
	}

	@Transactional(readOnly = true)
	public Document retrieveDocumentById(Integer id) {
		Document doc = (Document) entityManager.find(Document.class, id);
		if (logger.isInfoEnabled()) {
			logger.info("Found the following document: " + doc);
		}
		return doc;
	}

	@Transactional(readOnly = true)
	public Folder retrieveFolderById(Integer folderId) {
		if (logger.isInfoEnabled()) {
			logger.info("Retfieving Folder " + folderId);
		}
		return entityManager.find(Folder.class, folderId);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	@RemoteMethod
	public List<Folder> retrieveUserFolders(BriefcaseUser user) {
		Query q = entityManager.createNamedQuery("userFolders");
		q.setParameter(1, user.getUserName());
		return q.getResultList();
	}

	public DataFieldMaxValueIncrementer getFolderIdIncrementor() {
		return folderIdIncrementor;
	}

	public void setFolderIdIncrementor(
			DataFieldMaxValueIncrementer folderIdIncrementor) {
		this.folderIdIncrementor = folderIdIncrementor;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			throw new IllegalStateException(
					"sessionFactory has not been set on FolderDAO before usage");
		}
		return sessionFactory;
	}

	public Session getSession() {
		return getSessionFactory().getCurrentSession();
	}

}
